# -*- coding: utf-8 -*-
'''
###########################################
#  Created on 2011-10-25
#  @author: cl.lam
#  Description:
###########################################
'''
import os
import traceback
from datetime import date, datetime as dt
import urllib2
import json
import functools

import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
from email.header import Header
from PIL import Image


from flask import g, render_template, flash, session, redirect, url_for, request
from werkzeug import secure_filename
from flask import current_app as app
from sys2do.setting import UPLOAD_FOLDER, UPLOAD_FOLDER_PREFIX, \
    UPLOAD_FOLDER_URL, EMAIL_SERVER_IP, EMAIL_SEND_FROM
from sys2do.model import db
from sys2do.util.logic_helper import getCurrentUserID

__all__ = ['_g', '_gl', '_gp', '_gld',
           'number2alphabet', 'check_mobile',
           'upload', 'multiupload', 'sendMail']




def _g( name, default = None ):
    return request.values.get( name, default ) or default


def _gl( name ):
    return request.form.getlist( name )


def _gp( prefix ):
    return sorted( [( k, v or None ) for k, v in request.values.items() if k.startswith( prefix )], cmp = lambda x, y: cmp( x[0], y[0] ) )


def _getdict( f, *args ):
    result = {}
    for arg in args: result[arg] = f( arg )
    return result


_gld = functools.partial( _getdict, _g )



def number2alphabet( n ):
    result = []
    while n > 0 :
        x , y = n / 26, n % 26
        result.append( y )
        if x > 0 :
            n = x
        else:
            break

    p = 0
    for i in range( len( result ) ):
        result[i] += p
        if result[i] <= 0 and i + 1 < len( result ):
            result[i] += 26
            p = -1
        else:
            p = 0

    if result[-1] <= 0 : result = result[:-1]
    result.reverse()
    return "".join( map( lambda v:chr( v + 64 ), result ) )



def check_mobile( no ):
    if not no or not isinstance( no, basestring ): return False
    if not no.isdigit() : return False
    if len( no ) != 11 : return False    # china mobile is 11 length
    if  no[:2] not in ['13', '15'] : return False
    return True



def upload( name ):
    from sys2do.model import SysFile
    import random

    f = request.files.get( name, None )
    if not f : return None
    dir_path = os.path.join( UPLOAD_FOLDER_PREFIX, UPLOAD_FOLDER )
    if not os.path.exists( dir_path ) : os.makedirs( dir_path )
    ( pre, ext ) = os.path.splitext( f.filename )
    converted_name = "%s%s%s" % ( dt.now().strftime( "%Y%m%d%H%M%S" ), random.randint( 1000, 9999 ), ext )
    path = os.path.join( dir_path, converted_name )
    f.save( path )
    db_file_name = os.path.basename( f.filename )
    db_file_path = os.path.join( UPLOAD_FOLDER, converted_name )

    u = SysFile( createById = getCurrentUserID(), updateById = getCurrentUserID(),
                 createTime = dt.now(), updateTime = dt.now(),
                name = db_file_name,
                path = db_file_path,
                url = "/".join( [UPLOAD_FOLDER_URL, converted_name] ) )
    db.add( u )
    db.flush()
    return u


def multiupload( names = None ):
    # handle the upload file
    attachment_ids = []

    try:
        if names is None:
            for f in request.files:
                a = upload( f )
                if a : attachment_ids.append( a.id )
        else:
            for f in names:
                a = upload( f )
                if a : attachment_ids.append( a.id )

    except:
        pass
    return attachment_ids



def sendMail( send_to, subject, text, html, cc_to = [], files = [], server = EMAIL_SERVER_IP, send_from = EMAIL_SEND_FROM ):
    assert type( send_to ) == list
    assert type( files ) == list

    if not text and not html:
        raise "No content to send!"
    elif text and not html :
        msg = MIMEText( text, "plain", _charset = 'utf-8' )    # fix the default encoding problem
    elif not text and html:
        msg = MIMEText( html, "html", _charset = 'utf-8' )    # fix the default encoding problem
    else:
        msg = MIMEMultipart( "alternative" )
        msg.attach( MIMEText( text, "plain", _charset = 'utf-8' ) )
        msg.attach( MIMEText( html, "html", _charset = 'utf-8' ) )

    msg.set_charset( "utf-8" )
    if len( files ) > 0 :
        tmpmsg = msg
        msg = MIMEMultipart()
        msg.attach( tmpmsg )

    msg['From'] = send_from
    msg['To'] = COMMASPACE.join( send_to )

    if cc_to:
        assert type( cc_to ) == list
        msg['cc'] = COMMASPACE.join( cc_to )
        send_to.extend( cc_to )

    msg['Date'] = formatdate( localtime = True )
    msg['Subject'] = subject

    for f in files:
        part = MIMEBase( 'application', "octet-stream" )
        if isinstance( f, basestring ):
            part.set_payload( open( f, "rb" ).read() )
            Encoders.encode_base64( part )
            part.add_header( 'Content-Disposition', 'attachment; filename="%s"' % Header( os.path.basename( f ), 'utf-8' ) )
        elif hasattr( f, "file_path" ) and hasattr( f, "file_name" ):
            part.set_payload( open( f.file_path, "rb" ).read() )
            Encoders.encode_base64( part )
            part.add_header( 'Content-Disposition', 'attachment; filename="%s"' % Header( f.file_name, 'utf-8' ) )
        msg.attach( part )

    smtp = smtplib.SMTP( server )
    smtp.sendmail( send_from, send_to, msg.as_string() )
    smtp.close()



def makeThumb( fobj, size = ( 50, 50 ) ):
    from sys2do.model import SysFile
    if not fobj : return None
    ext = os.path.splitext( fobj.name )[1].lower()[1:]
    if ext not in ['bmp', 'gif', 'jpg', 'png'] : return None

    try:
        def _f( p ):
            tmp = os.path.splitext( p )
            return "".join( [tmp[0], '_thumb', tmp[1]] )

        a = Image.open( fobj.realPath )
        a.thumbnail( size )
        thname = _f( fobj.name )
        thpath = _f( fobj.path )
        thurl = _f( fobj.url )

        a.save( _f( fobj.realPath ) )

        u = SysFile( createById = getCurrentUserID(), updateById = getCurrentUserID(),
                     createTime = dt.now(), updateTime = dt.now(),
                     name = thname, path = thpath, url = thurl, type = ext )
        db.add( u )
        db.flush()
        return u
    except:
        traceback.print_exc()
        return None
